#include<stdio.h>
#define maxsize 7
typedef struct 
{
    char data;
    int next;
}module;
void backuplist(module *p);//备份结构体数组到另一个链表里面
int staticlist(module *p);//初始化静态链表
void insertA(module *p,int chain,int add,char a);//向链表里面插入数据
void deleteA(module *p,int chain,char a);//删除链表中含有字符a的节点
int  selectstone(module *p,int chain,char stone);//查找stone节点在数组的位置
void updatestone(module *p,int chain,char oldstone,char newstone);//更新链表中的stone节点
void printchain(module *p,int chain);
int mallocarr(module *p);
void freearr(module *p,int k);

int main()
{
    module p[maxsize];
    int chain=staticlist(p);
    printf("the Static linked list is:\n");
    printchain(p,chain);
    printf("insert the 'e' on the 3th point.\n");
    insertA(p,chain,3,'e');
    printchain(p,chain);
    printf("Delete the node with data field a.\n");
    deleteA(p,chain,'a');
    printchain(p,chain);
    printf("seek the node with data field e.\n ");
    int selectAdd=selectstone(p,chain,'e');
    printf("%d\n",selectAdd);
    printf("change the node data from 'e' to 'h'.\n");
    updatestone(p,chain,'e','h');
    printchain(p,chain);
    return 0;

}
void backuplist(module *p)//创建备用链表,这个函数是为了连接结构体数组与链表
{
    for(int i=0;i<maxsize;i++)
    {
        p[i].next=i+1;//每个数组的分量连接在一起
    }
    p[maxsize-1].next=0;//链表最后一个节点的游标值为0
}
//提取分配空间
int mallocarr(module *p)//定义好备用链表
{
    //备用链表非空，则返回分配的节点下标，否则返回0
    int i=p[0].next;
    if(p[0].next)//备用链表前一个节点的值不是0，则把下一个节点的值赋给它
    {
        p[0].next=p[i].next;
    }
    return i;
}
//初始化静态链表
int staticlist(module *p)
{
    backuplist(p);
    int chain=mallocarr(p);
//声明一个变量，把它当作指针，指向链表的最后一个节点，因为链表是空的，所以和头节点重合
int tempchain=chain;
for(int i=1;i<5;i++)
{
    int j=mallocarr(p);
    p[tempchain].next=j;
    p[j].data='a'+i-1;//初始化数据领域
    tempchain=j;
}
p[tempchain].next=0;
return chain;

}
void insertA(module *p,int chain,int add,char a)
{
    int tempchain=chain;
    for(int i=1;i<add;i++)
    {
        tempchain=p[tempchain].next;

    }
    int insert=mallocarr(p);//申请空间
    p[insert].next=p[tempchain].next;//插入节点的游标等于插入位置的上一个游标
    p[insert].data=a;
    p[tempchain].next=insert;//让上一个节点的游标等于插入节点所在数组中的位置的下标
}
void deleteA(module *p,int chain,char a)
{
    int tempchain=chain;
    while(p[tempchain].data!=a)
    {
        tempchain=p[tempchain].next;
        if(tempchain==0)
        {
            printf("no data in this link list.\n");
            return ;
        }
    }
    int del=tempchain;
    tempchain=chain;
    //找到上一个节点，做删除操作
    while(p[tempchain].next!=del)
    {
        tempchain=p[tempchain].next;
    }
    p[tempchain].next=p[del].next;
    freearr(p,del);
}
int  selectstone(module *p,int chain,char stone)
{
    int tempchain=chain;
    while (p[tempchain].next!=0)
    {
        if(p[tempchain].data==stone)
        {
            return tempchain;
        }
        tempchain=p[tempchain].next;
    }
    return -1;
}
void updatestone(module *p,int chain,char oldstone,char newstone)
{
    int add=selectstone(p,chain,oldstone);
    if(add==-1)
    {
        printf("no changed data\n");
        return;
    }
    p[add].data=newstone;

}
void printchain(module *p,int chain)
{
    int tempchain=chain;   //tempchain准备遍历
    while(p[tempchain].next)
    {
        printf("%c,%d",p[tempchain].data,p[tempchain].next);
        tempchain=p[tempchain].next;

    }
    printf("%c,%d\n",p[tempchain].data,p[tempchain].next);

}
void freearr(module *p,int k)
{
    p[k].next=p[0].next;
    p[0].next=k;
}